
(**
Interaction with Mathematica is just a parsing problem.  
Given a file "math.m" with some declarations, running 

  math < math.m > out.txt 

will have Mathematica process the file and put redirect the output. 

For regularity, we wrap key/value pairs together in a list.

So to get both the values of 1 + 2 and 2 + 3, you'd invent names,
and send Mathematica the string

{{"x","1 + 2"},{"y","2 + 3"}}

For instance,  for math.m with contents 

    {
     {"sign",Pi >= 0},
     {"digits",RealDigits[Pi,2,54]}
    }

The result is:

    Mathematica 5.2 for Students: Mac OS X Version
    Copyright 1988-2005 Wolfram Research, Inc.

    In[1]:= 
    In[1]:= 
    In[1]:= 
    Out[1]= {{sign, True},{digits, {{1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 

    >      1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 

    >      1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}, 2}}}

    In[2]:= 

*)


(**
mathematica [(x1,exp1); (x2,exp2); ...]

run mathematica on the file

{
  {"x_1",exp_1},
  ...
  {"x_n",exp_n},
}

and get the result, 

{
  {x_1,res_1},
  ...
  {x_n,res_n}
}

Keep in mind that this is just raw output, so the 'mathematica' function
lexes away newline characters and the '>' characters that indicate Mathematica
newlines in the output.  ** If the user needs '>' in the output, she must
change the lexer/parser in mathematica.ml **
 *)

val mathematica : (string * string) list -> (string * string) list
  (** The main command. *)

val temp_dir : string ref
(**
   directory for temp files, default is "/tmp".
 *)

val preamble : string list ref
  (**
     command to execute before beginning computation, such
     as file loading
  *)

val dirs : string list ref
  (**
     Where to search for files in the [preamble].
  *)

val mathematica_command : string ref
  (** 
      Set the path to the mathematica command line binary, usually called 
      'MathKernel'  or 'math'.
      On OSX, mine lives here: '/Applications/mathematica/Contents/MacOS/math'
  *)

type 'a parser = 'a Parse.parser
    (** 
        While in genearal you'll have to write your own parser to interpret the output,
        there are some common mathematica idioms that can be parsed easily.  
        Some examples are given below.  
    *)

val parse_mlist : 'a parser -> 'a list parser
    (** parse a list {x1,x2,...,xn} with the same parser *)

val parse_mpair : 'a parser -> 'b parser -> ('a * 'b) parser
    (** parse a pair with two different parsers*)

val parse_bool : bool parser
    (** parse a 'True' or 'False' *)
